﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace DBUtil
{
    internal static class Util
    {


        internal static DbType GetValueDbType(object objvalue, DbParameter para)
        {
            Type tyval = objvalue.GetType();
            Type typeVal = Nullable.GetUnderlyingType(tyval) ?? tyval;

            DbType dbType = DbType.AnsiString;
            DateTime dtime;
            Guid gid;
            if (typeVal.IsEnum && Enum.GetUnderlyingType(typeVal) == typeof(byte))
            {
                dbType = DbType.Int32;
            }
            else if (typeVal == typeof(byte[]))
            {
                dbType = DbType.Binary;
            }
            else if (DateTime.TryParse(objvalue.ToString(), out dtime)
               && !Regex.IsMatch(objvalue.ToString(), @"^\d{4}[.-/]{1}\d{1,2}$"))
            {
                dbType = DbType.DateTime;
            }
            else if (Guid.TryParse(objvalue.ToString(), out gid))
            {
                dbType = DbType.String;
                para.Value = objvalue.ToString();
            }
            else
            {

            }
            return dbType;
        }

        public static Hashtable ConvertHashTable<T>(object obj, string[] excludeFields, params Attribute[] excludeAttr)
        {
            Hashtable ht = new Hashtable();

            List<string> lstExcludeField = new List<string>();
            if (excludeFields != null && excludeFields.Length > 0)
            {
                lstExcludeField = excludeFields.Select(t => t.ToLower()).ToList();
            }
            List<string> lstAllField = new List<string>();
            Type tyTable = typeof(T);
            PropertyInfo[] pyInfos = tyTable.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            foreach (PropertyInfo pInfo in pyInfos)
            {
                if (excludeAttr != null && excludeAttr.Length > 0)
                {
                    bool isBK = false;
                    Attribute[] attrs = pInfo.GetCustomAttributes(true) as Attribute[];
                    if (attrs != null && attrs.Length > 0)
                    {
                        foreach (var attr in attrs)
                        {
                            foreach (var item in excludeAttr)
                            {
                                if (attr.GetType() == item.GetType())
                                {
                                    isBK = true;
                                    break;
                                }
                            }
                            if (isBK)
                            {
                                break;
                            }
                        }
                        if (isBK)
                        {
                            continue;
                        }
                    }
                }
                string name = pInfo.Name.ToString().ToLower();
                object objvalue = null;

                if (obj is T && !lstExcludeField.Contains(name))
                {
                    objvalue = pInfo.GetValue((T)obj, null);
                    ht.Add(name, objvalue);
                }

                //存储对象 所有小写形式的属性
                lstAllField.Add(name);
            }

            if (obj is IDictionary)
            {
                IDictionary dict = ((IDictionary)obj);
                foreach (DictionaryEntry entry in dict)
                {
                    string name = entry.Key.ToString().ToLower();
                    if (lstAllField.Contains(name) && !lstExcludeField.Contains(name))
                    {
                        ht.Add(name, entry.Value);
                    }
                }
            }
            else if (obj is NameValueCollection)
            {
                NameValueCollection nvc = obj as NameValueCollection;
                foreach (string key in nvc.AllKeys)
                {
                    string name = key.ToLower();
                    if (lstAllField.Contains(name) && !lstExcludeField.Contains(name))
                    {
                        ht.Add(name, nvc[key]);
                    }
                }
            }

            return ht;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static List<T> GetFirstCol<T>(this DataTable data, string columnName = "")
        {
            List<T> lst = new List<T>();
            if (data == null || data.Rows.Count <= 0)
            {
                return lst;
            }
            else
            {
                foreach (DataRow dr in data.Rows)
                {
                    if (!string.IsNullOrWhiteSpace(columnName))
                    {
                        if (dr[columnName] != null)
                        {
                            T t = (T)Convert.ChangeType(dr[columnName], typeof(T));
                            lst.Add(t);
                        }
                    }
                    else
                    {
                        if (dr[0] != null)
                        {
                            T t = (T)Convert.ChangeType(dr[0], typeof(T));
                            lst.Add(t);
                        }
                    }
                }
            }
            return lst;
        }


        public static Dictionary<Key, Val> GetDict<Key, Val>(this DataTable data, string ColumnNameKey, string ColumnVal)
        {
            Dictionary<Key, Val> dict = new Dictionary<Key, Val>();
            if (data == null || data.Rows.Count <= 0)
            {
                return new Dictionary<Key, Val>();
            }
            else
            {
                foreach (DataRow dr in data.Rows)
                {
                    Key k = (Key)Convert.ChangeType(dr[ColumnNameKey], typeof(Key));
                    Val v = (Val)Convert.ChangeType(dr[ColumnVal], typeof(Val));

                    dict.Add(k, v);
                }
            }
            return dict;
        }


        public static string SqlIn<T>(string field, T[] members, bool isNotIn = false)
        {
            string result = string.Empty;
            if (members == null || members.Length <= 0)
            {
                return string.Empty;
            }
            List<string> lst = new List<string>();
            foreach (T obj in members)
            {
                if (obj != null)
                {
                    string val = obj.ToString();
                    if (val.StartsWith("'") && val.EndsWith("'"))
                    {
                        val = val.Replace("'", "'''");
                        lst.Add(val);
                        continue;
                    }
                    lst.Add("'" + val + "'");
                }
            }
            if (lst.Count > 0)
            {
                result = " and " + field + " " + (isNotIn ? "not" : "") + " in (" + string.Join(",", lst) + ") ";
            }
            return result;
        }


        public static string SqlLike<T>(string field, T[] members, bool isOrLike = true)
        {
            string result = string.Empty;
            if (members == null || members.Length <= 0)
            {
                return string.Empty;
            }
            List<string> lst = new List<string>();
            foreach (T obj in members)
            {
                if (obj != null)
                {
                    string like_sql = field + " like '%{0}%' ";
                    string temp_sql = string.Empty;
                    string val = obj.ToString();
                    if (val.StartsWith("'") && val.EndsWith("'"))
                    {
                        val = val.Replace("'", "''");
                        temp_sql = string.Format(like_sql, val);
                        lst.Add(temp_sql);
                        continue;
                    }
                    temp_sql = string.Format(like_sql, val);
                    lst.Add(temp_sql);
                }
            }
            if (lst.Count>0)
            {
                result = " and (" + (string.Join((isOrLike ? " or" : " and "), lst)) + ") ";
            }            
            return result;
        }

        public static Hashtable ToHashtable(this NameValueCollection param)
        {
            Hashtable ht = new Hashtable();
            foreach (string key in param.AllKeys)
            {
                string name = key;
                string value = param[key];
                ht.Add(name, value);
            }
            return ht;
        }




        /// <summary>
        /// 创建指定 列名字的数据表
        /// </summary>
        /// <param name="columnNames">数据列名</param>
        /// <returns></returns>
        public static DataTable CreateDataTable(params string[] columnNames)
        {
            DataTable data = new DataTable();
            if (columnNames != null && columnNames.Length > 0)
            {
                data.Columns.AddRange(columnNames.Select(t => new DataColumn(t)).ToArray());
            }
            return data;
        }


     



    }
}
